from rest_framework.serializers import ModelSerializer,Serializer
from .models import UserProfile,Grade
from rest_framework import serializers
from django.contrib.auth import get_user_model
from MxOnline.settings import REGEX_MOBILE
from .models import VerifyCode
from django.contrib.auth.hashers import make_password
import re
import datetime
from rest_framework.validators import UniqueValidator
import pytz


User = get_user_model()


class UserInfoSerializer(ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ["id","username","email","avator","gender","usertype","mobile","avator_url"]


class UserSummarySerializer(ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ["id","username","avator","usertype","avator_url"]


class GradeInfoSerializer(ModelSerializer):
    teacher = serializers.StringRelatedField()

    class Meta:
        model = Grade
        fields = ["GradeName","teacher","id"]


class GradeDetailInfoSerializer(ModelSerializer):
    teacher = serializers.StringRelatedField()
    from course.serializer import CourseSummarySerializer
    course = CourseSummarySerializer(read_only=True,many=True)

    class Meta:
        model = Grade
        fields = ["GradeName","teacher","id","course"]


class SmsSerializer(Serializer):
    mobile = serializers.CharField(max_length=11,help_text="手机号")

    def validate_mobile(self,mobile):
        """
        验证手机号码
        :param attrs:
        :return:
        """
        # 手机是否注册
        if User.objects.filter(mobile=mobile).count()>0:
            raise serializers.ValidationError("用户已经存在")
        # 验证手机号码合法

        if not re.match(REGEX_MOBILE,mobile):
            raise serializers.ValidationError("手机号码非法")
        # 验证码发送频率
        one_minutes_ago = datetime.datetime.now() - datetime.timedelta(
            hours=0,minutes=1,seconds=0
        )
        if VerifyCode.objects.filter(add_time__gt=one_minutes_ago,mobile=mobile):
            raise serializers.ValidationError("距离上一次发送未超过60s")
        return mobile


class UserRegisterSerialier(serializers.ModelSerializer):
    code = serializers.CharField(required=True,max_length=4,write_only=True,min_length=4,help_text="验证码",
                                 error_messages = {
                                     "blank":"请填写验证码",
                                     "required":"请填写验证码",
                                     "max_length":"验证码格式错误",
                                     "min_length":"验证码格式错误",
                                 })
    username = serializers.CharField(required=True,allow_blank=False,label="用户名",help_text="用户名",
                                     validators=[UniqueValidator(queryset=User.objects.all(),message="用户以存在"),],
                                     )
    password = serializers.CharField(
        style={"input_type":"password"},label="密码",write_only=True,help_text="密码"
    )

    def validate_code(self,code):
        verify_records = VerifyCode.objects.filter(code=code,mobile=self.initial_data["username"]).order_by("add_time")
        if verify_records:
            last_record = verify_records[0]
            five_mintes_age = datetime.datetime.now() - datetime.timedelta(hours=0,minutes=5,seconds=0)
            if five_mintes_age.replace(tzinfo=pytz.timezone('Asia/Shanghai')) > last_record.add_time:
                raise serializers.ValidationError("验证码过期")
            if last_record.code !=code:
                raise serializers.ValidationError("验证码错误")
        else:
            raise serializers.ValidationError("验证码错误")

    def validate_usertype(self,data):
        if data not in ["teacher","student"]:
            raise serializers.ValidationError("用户类型错误")
        return data

    def validate(self, attrs):
        attrs["mobile"] = attrs["username"]
        del attrs["code"]
        attrs["password"] = make_password(attrs["password"])
        return attrs

    class Meta:
        model = User
        fields = ("username","mobile","password","usertype","code")


class GenericNotificationRelatedField(serializers.RelatedField):
    def to_representation(self, value):
        serializer = GradeInfoSerializer(value)

        return serializer.data


class MessageSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    recipient = UserSummarySerializer(read_only=True)
    unread = serializers.BooleanField(read_only=True)
    target = GenericNotificationRelatedField(read_only=True)
    verb = serializers.CharField(read_only=True)
    timestamp = serializers.DateTimeField(read_only=True,format="%Y-%m-%d %H:%M")


class MessageDetailSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    recipient = UserSummarySerializer(read_only=True)
    unread = serializers.BooleanField(read_only=True)
    target = GenericNotificationRelatedField(read_only=True)
    verb = serializers.CharField(read_only=True)
    timestamp = serializers.DateTimeField(read_only=True,format="%Y-%m-%d %H:%M")
    description = serializers.CharField(read_only=True)
